package com.bbm.communitysystem.config;

import cn.hutool.core.bean.BeanUtil;
import com.bbm.communitysystem.core.generate.HeadImg;
import com.bbm.communitysystem.core.oss.OSS;
import com.bbm.communitysystem.core.redis.PerRedis;
import com.bbm.communitysystem.core.redis.RoleRedis;
import com.bbm.communitysystem.domain.*;
import com.bbm.communitysystem.domain.bo.HouseholdBo;
import com.bbm.communitysystem.domain.bo.UserCredBo;
import com.bbm.communitysystem.domain.dto.FamilyDto;
import com.bbm.communitysystem.domain.dto.UserCredDto;
import com.bbm.communitysystem.domain.dto.UserInfoDto;
import com.bbm.communitysystem.service.IFamilyService;
import com.bbm.communitysystem.service.IRoleService;
import com.bbm.communitysystem.service.IUserCredService;
import com.bbm.communitysystem.service.IUserInfoService;
import com.bbm.communitysystem.service.impl.HouseholdServiceImpl;
import com.bbm.communitysystem.service.impl.OssFileServiceImpl;
import com.bbm.communitysystem.service.impl.PerServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;

@Slf4j
@Configuration
@RequiredArgsConstructor
public class AppConfig {

    private final PerRedis perRedis;

    private final RoleRedis roleRedis;

    private final IRoleService roleService;

    private final PerServiceImpl perService;

    private final IUserCredService userCredService;

    private final IFamilyService familyService;

    private final HouseholdServiceImpl householdService;

    private final IUserInfoService userInfoService;

    private final HeadImg headImg;

    private final OSS oss;

    private final OssFileServiceImpl ossFileService;



    @Bean
    public String initFilter() {
        log.info("初始化过滤器");
        log.info("初始化权限");
        perService.lambdaQuery()
                .eq(Per::getStatus, 1)
                .list().forEach(per -> {
                   perRedis.setValue(per.getPerPath(), per);
               });
        log.info("初始化权限结束");
        log.info("初始化角色");
        roleService.lambdaQuery()
                .eq(Role::getStatus, 1)
                .list().forEach(role -> {
                    roleRedis.setRole(role.getId() + "", role);
                });
        log.info("初始化角色结束");

        return "filter";
    }


    @Bean
    @Transactional
    public String appInit() {

        Role admin = roleService.lambdaQuery()
                .eq(Role::getRoleName, "admin")
                .one();

        if (admin == null) {
            admin = new Role();
            admin.setRoleName("admin");
            admin.setStatus(1 + "");
            admin.setUpdateBy("0");
            admin.setRolePerId("");
            admin.setRouterIds("");
            admin.setRoleDescription("系统管理员");
            admin.setUpdateTime(System.currentTimeMillis() + "");

            boolean save = roleService.save(admin);

            if (!save) {
                throw new RuntimeException("创建管理员角色失败");
            }

        }

         UserCred one = userCredService.lambdaQuery()
                .eq(UserCred::getUserName, "admin")
                .one();

         if (one == null) {
             UserCredBo userCredBo = new UserCredBo();
             userCredBo.setUserName("admin");
             userCredBo.setPassword("123456");

             MessageDigest messageDigest;

             try {
                 messageDigest = MessageDigest.getInstance("SHA-256");
             } catch (NoSuchAlgorithmException e) {
                 throw new RuntimeException(e);
             }
             messageDigest.update(userCredBo.getPassword().getBytes());
             String passwd = byte2Hex(messageDigest.digest());

             userCredBo.setPassword(passwd);

             UserCredDto userCredDto = userCredService.registerUserCredDto(userCredBo);

             UserInfo userInfo = new UserInfo();

             userInfo.setUserNick(userCredDto.getUserName());
             userInfo.setUserSex(1);
             userInfo.setIsSun(0);

             byte[] bytes = new byte[0];
             try {
                 bytes = headImg.generateImg("admin");
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }

             List<OssFile> ossFiles = oss.saveFile("headImg", userCredDto.getId() + "", bytes);

             userInfo.setUserImg(ossFiles.get(0).getClientUrl());
             userInfo.setOssId(ossFiles.get(0).getId());
             userInfo.setUserEmail("none");
             userInfo.setUserBirthDate("2000-01-01");
             userInfo.setCommunityId(0);
             userInfo.setUserRoleId(admin.getId() + "");
             userInfo.setStatus(1);
             userInfo.setUserBirthDate("2000-01-01");
             userInfo.setCredId(userCredDto.getId());
             userInfo.setUpdateBy(userCredDto.getId() + "");
             userInfo.setUpdateTime(System.currentTimeMillis() + "");

             boolean save = userInfoService.save(userInfo);

             if (!save) {
                 throw new RuntimeException("创建管理员用户失败");
             }

             initUserInfo(BeanUtil.copyProperties(userInfo, UserInfoDto.class));

         }



        return "app";
    }

    public void initUserInfo (UserInfoDto userCredDto) {


        //创建用户家庭
        FamilyDto familyDto = new FamilyDto();
        familyDto.setFamilyName(userCredDto.getUserNick() + "的家庭");
        familyDto.setUpdateBy(userCredDto.getId() + "");
        FamilyDto family = familyService.createFamily(familyDto);

        if (family == null) {
            throw new RuntimeException("创建家庭失败");
        }

        //创建用户住户信息
        HouseholdBo householdBo = new HouseholdBo();
        householdBo.setFamilyId(family.getId());
        householdBo.setUserId(userCredDto.getId());


        householdBo.setUpdateBy(userCredDto.getId() + "");
        int household = householdService.createHousehold(householdBo);

        if (household == 0) {
            throw new RuntimeException("创建住户信息失败");
        }

    }

    private static String byte2Hex(byte[] bytes) {
        StringBuilder stringBuilder = new StringBuilder();
        String temp;
        for (byte aByte : bytes) {
            temp = Integer.toHexString(aByte & 0xFF);
            if (temp.length() == 1) {
                stringBuilder.append("0");
            }
            stringBuilder.append(temp);
        }
        return stringBuilder.toString();
    }

}
